<template>
  <div class="test">
    <div id="map" class="map" ref="MyMap" onselectstart="return false">
      <div id="swipeContainer" @mousemove="move" v-if="isSlider">
        <div id="swipeDiv">
          <div class="handle"></div>
        </div>
      </div>
    </div>
    <div class="tools">
      <el-select v-model="geometryVal" placeholder="请选择" @change="changeGeometry">
        <el-option
            v-for="item in geometryType"
            :key="item.value"
            :label="item.label"
            :value="item.value">
        </el-option>
      </el-select>
      <el-button type="primary" @click="getCity">绘制城市边界</el-button>
      <el-button type="primary" @click="setBoundaryMask">设置边界外遮罩</el-button>
      <el-button type="primary" @click="lengthMeasure()">测距</el-button>
      <el-button type="primary" @click="areaMeasure">测面</el-button>
      <el-button type="primary" @click="rollingCurtain">卷帘</el-button>
      <el-button type="primary" @click="showPop">弹窗</el-button>
      <el-button type="primary" @click="vectorHigh">矢量图高亮</el-button>
    </div>
    <div ref="popup" class="popup">
      <span class="icon-close" @click="closePopup">✖</span>
      <div class="content">{{ currentCoordinate }}</div>
    </div>
    <div class="explain">
      <p>
        overlay：叠加层，即叠加到地图上显示的元素，
        关联了一个自定义的HTML元素，由一个单一的地图坐标点确定叠加位置。
        与控件类似，但不同的是叠加元素不是在一个固定的屏幕位置上，
        而是通过关联一个地图逻辑坐标点跟随地图移动，如标注点、popup等。
      </p>
    </div>
  </div>
</template>
<script>
// 映入css文件、
import "ol/ol.css";
import "../utils/openlayers/css/OverviewMap.css";
import Map from "ol/Map.js";
import Overlay from "ol/Overlay";
import View from "ol/View.js";
// 地图服务
import {
  tiandituImgMap
} from "@/utils/openlayers/js/mapServer";
import {Fill, Stroke, Circle, Style} from "ol/style.js";
import VectorLayer from 'ol/layer/Vector.js';
// 绘制数据源
import VectorSource from 'ol/source/Vector.js';
// 绘制事件
import Draw, {createRegularPolygon} from 'ol/interaction/Draw.js'
import {defaults} from "ol/control"
import {DoubleClickZoom} from "ol/interaction"
import {ajaxget} from "@/api";
import {Polygon, MultiPolygon} from "ol/geom";
import {Feature} from "ol";
import {fromExtent} from "ol/geom/Polygon";
import LinearRing from "ol/geom/LinearRing";
import MapToolMixin from "@/utils/common/mapTool.mixin"
let drawLayer = null, editSource = null
export default {
  data() {
    return {
      map: null,
      center: [113, 23],//设置地图默认中心点
      projection: 'EPSG:4326',//坐标系
      zoom: 10,
      geometryType: [
        {
          value: 'None',
          label: '无'
        },
        {
          value: 'Point',
          label: '点'
        },
        {
          value: 'LineString',
          label: '线'
        },
        {
          value: 'Polygon',
          label: '多边形'
        },
        {
          value: 'Circle',
          label: '圆'
        },
        {
          value: 'Square',
          label: '正方形'
        },
      ],
      geometryVal: '',
      featuresArr: [],
      editLayer: null,
      swipe: {},
      value: 50,
      layer: {},
      isSlider: false,
      overlay: null,
      currentCoordinate: '',

    };
  },
  mixins: [MapToolMixin],
  mounted() {
    this.initMap();
  },
  methods: {
    initMap() {
      this.map = new Map({
        target: "map",
        view: new View({
          projection: this.projection || "EPSG:4326",
          center: this.center || [0, 0],
          zoom: this.zoom || 2
        }),
        controls: defaults({
          zoom: false,
        })
      });
      const dblClickInteraction = this.map
          .getInteractions()
          .getArray()
          .find(interaction => {
            return interaction instanceof DoubleClickZoom;
          });
      this.map.removeInteraction(dblClickInteraction);

      let layer = tiandituImgMap(this.map)
      this.layer = layer.TiandiMap_img
      this.initStyle()
      let that = this
      this.map.on('dblclick', function () {
        that.map.removeInteraction(drawLayer)
      })

    },
    initStyle() {
      editSource = new VectorSource()
      this.editLayer = new VectorLayer({
        source: editSource,
        style: new Style({
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.4'
          }),
          stroke: new Stroke({
            color: '#00c033',
            width: 4
          }),
          image: new Circle({
            radius: 7,
            fill: new Fill({
              color: '#00c033'
            })
          })
        })
      })
      this.map.addLayer(this.editLayer)
    },
    changeGeometry(val) {
      this.map.removeInteraction(drawLayer)
      this.addInteraction(val)
    },
    addInteraction(val) {
      let typeVal = val
      // eslint-disable-next-line no-unused-vars
      let coordinates = ''
      if (val !== 'None') {
        let geometryFun = null, maxPoints = null;
        if (val === 'Square') {
          typeVal = 'Circle'
          geometryFun = createRegularPolygon(4)
        } else if (val === "Rectangle") {
          val = 'LineString';
          maxPoints = 2;
          geometryFun = function (coordinates, geometry) {
            //如果geometry对象不存在或者为空，则创建
            if (!geometry) {
              //多面几何图形下设置
              geometry = new Polygon()
            }
            // 开始坐标
            let start = coordinates[0];
            // 结束坐标
            let end = coordinates[1];
            // 根据开始与结束坐标绘制,从起始点，回到起始点
            geometry.setCoordinates([[
              start, [start[0], end[1]], end, [end[0], start[1]], start]
            ]);
            // 返回几何图形坐标进行渲染
            return geometry;
          }
        } //当为线类型时，限制最大点数为2
        else if (val === "LineString") {
          maxPoints = 2;
        } else if (val === "Point") {
          maxPoints = 1;
        }
        drawLayer = new Draw({
          source: editSource,
          type: typeVal,
          geometryFunction: geometryFun,
          maxPoints: maxPoints,
          stopClick: true
        })
        this.map.addInteraction(drawLayer)
        //当画图结束后，获取画图形状的坐标
        drawLayer.on("drawend", function (event) {
          if (val == "Circle") {
            // 圆心
            let center = event.feature.getGeometry().getCenter();
            // 半径
            let radius = event.feature.getGeometry().getRadius();
            coordinates = "圆心：" + center + "半径：" + radius;
          } else {
            coordinates = event.feature.getGeometry().getCoordinates();
          }
          // document.getElementById('coordinates').innerHTML = coordinates
        }, this)
      } else {
        //清空绘制的图形
        editSource.clear()
      }
    },
    //  绘制省市县
    getCity() {
      ajaxget("/mock/mock.json").then(res => {
        let features = [];
        let lineData = res.features[0]
        let routeFeature = "";
        if (lineData.geometry.type == "MultiPolygon") {
          routeFeature = new Feature({
            geometry: new MultiPolygon(lineData.geometry.coordinates),
          });
        } else if (lineData.geometry.type == "Polygon") {
          routeFeature = new Feature({
            geometry: new Polygon(lineData.geometry.coordinates),
          });
        }
        routeFeature.setStyle(
            new Style({
              fill: new Fill({
                color: "#4e98f444", //填充颜色
              }),
              stroke: new Stroke({
                width: 3, //边界宽度
                color: [71, 137, 227, 1], //边界颜色
              }),
            })
        );
        features.push(routeFeature);
        // 设置图层
        let routeLayer = new VectorLayer({
          source: new VectorSource({
            features: features
          })
        });
        // 只显示某一个行政区域
        this.featuresArr.push(routeLayer);
        if (this.map) {
          //清除所有的feature
          this.featuresArr.slice(0, this.featuresArr.length - 1).map(item => {
            item.getSource().getFeatures().forEach((feature) => {
              item.getSource().removeFeature(feature)
            })
          })

          //  设置地图与缩放级别
          this.map.getView().setCenter(lineData.properties.center)
          this.map.getView().setZoom(6)
          // 添加图层
          setTimeout(() => {
            this.map.addLayer(routeLayer);
          }, 100);
        }
      })
    },
    getErase(geom) {
      let extent = [-180, -90, 180, 90]
      let polygonRing = fromExtent(extent)
      let coords = geom.coordinates
      coords.forEach(coord => {
        let linearRing = new LinearRing(coord[0])
        polygonRing.appendLinearRing(linearRing)
      })
      return polygonRing
    },
    //设置边界外遮罩
    setBoundaryMask() {
      let that = this
      ajaxget("/mock/hebei.json").then(res => {
        let coverGeom = that.getErase(res.features[0].geometry)
        let covertFt = new Feature({
          geometry: coverGeom
        })
        let myStyle = new Style({
          fill: new Fill({
            color: 'rgba(255,255,255,0.7)'
          }),
          stroke: new Stroke({
            lineDash: [1, 2, 3, 4, 5],
            color: '#ffcc33',
            width: 4,
          }),
        })
        this.editLayer = new VectorLayer({
          source: new VectorSource(),
          style: myStyle,
        })
        this.featuresArr.push(this.editLayer);
        //清除所有的feature
        this.featuresArr.slice(0, this.featuresArr.length - 1).map(item => {
          item.getSource().getFeatures().forEach((feature) => {
            item.getSource().removeFeature(feature)
          })
        })
        let lineData = res.features[0]
        this.editLayer.getSource().addFeature(covertFt);
        this.map.getView().setCenter(lineData.properties.center)
        this.map.getView().setZoom(8)
        this.map.addLayer(this.editLayer)
      });
    },
    rollingCurtain() {
      this.isSlider = true
      this.LayerSwipes();
    },
    // 关闭弹窗
    closePopup() {
      this.overlay.setPosition(undefined)
      this.currentCoordinate = null
    },

  },
  updated() {
    this.map.render();
    this.map.updateSize();
  },
};
</script>
<style lang="stylus" scoped>
@import '~@/map/css/index.styl';
</style>


